<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
  <button onclick="clearTimer()">取消</button>
</body>
<script>
  /**
   * 创建一个带有取消功能的定时器
   * 类似于 setInterval，但这个定时器可以被取消，并且能够处理由于执行时间超过间隔时间导致的累积执行问题
   *
   * @param {Function} fn 要定时执行的函数
   * @param {number} delay 执行间隔时间（毫秒）
   * @returns {Object} 返回一个对象，包含一个取消定时器的方法
   */
  function mySetInterval(fn,delay){
    // 存储当前 setTimeout 的 ID
    let timeOutId = null
    // 记录上次执行 fn 的时间
    let lastTime = Date.now()

    // 定义一个自调用的函数来处理定时执行逻辑
    function timeInterval(){
      // 使用 setTimeout 来模拟 setInterval 的行为
      timeOutId = setTimeout(() => {
        // 执行传入的函数
        fn()
        // 更新上次执行时间
        lastTime = Date.now()
        // 递归调用自身以实现循环执行
        timeInterval()
      }, delay - (Date.now() - lastTime))
    }

    // 启动定时器
    timeInterval()

    // 返回一个对象，提供取消定时器的方法
    return {
      cancel: () => {
        // 清除当前的 setTimeout
        clearTimeout(timeOutId)
      }
    }
  }

  const interval = mySetInterval(()=>{
    console.log(Date.now())
  },1000)
  function clearTimer(){
    interval.cancel()
  }
</script>
</html>
